package chat;

import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import main.CurrentState;
import voSetting.ChattingVO;
import voSetting.PortVO;


public class ChatClientThread extends Thread{
	Chatting chatting;														
	CurrentState current;	
	Socket socket;						
	InputStream is;						
	ObjectInputStream ois;
	
	OutputStream os;					
	ObjectOutputStream oos;										
	
	boolean flag = true;				
	
	public ChatClientThread(Chatting chatting, Socket s){		
		this.chatting = chatting;					
		this.socket = s;
		start();						
				
	}
	String myIcon = "C:\\Program Files\\Mino Corp\\profile\\myprofile.png";
	String anotherIcon = "C:\\Program Files\\Mino Corp\\profile\\another.png";
	
	StyledDocument doc;
	StyledDocument cur;
	SimpleAttributeSet name;
	SimpleAttributeSet message;
	SimpleAttributeSet labelStyle;
	SimpleAttributeSet date;


	public void run(){	
		try {									
			os = socket.getOutputStream();				
			oos = new ObjectOutputStream(os);	 	
																		
			is = socket.getInputStream();				
			ois = new ObjectInputStream(is);			
			
			while(flag){									
				ChattingVO chattingVO = (ChattingVO)ois.readObject();
				//PortVO portVO = (PortVO) ois.readObject();
				switch(chattingVO.getCommand()){
				 	case 1 : // connect
				 		chatting.dl_chatter.removeAllElements();	// 1-1) listModel(접속한 사람)을 초기화한다. 
				 		//chatting.dl_chatter.clear();
				    	Vector<String> v = (Vector) chattingVO.getObj();
				 		for(String str : v){						// 1-3) 벡터값을 스트링으로 하나씩(str) 받아오고,  이를 listModel에 더해준다. 
				    		chatting.dl_chatter.addElement(str);
				    		System.out.println("채팅클라이언트쓰레드에서 str 출력 : "+str);
				    	}
//				 		if(chattingVO.getE_name() != str){
//	                         chatting.dl_chatter.addElement(str);
//	                      }else{
//	                         
//	                      }
				 		if(chatting.dl_chatter.size()>=3){
				 			chatting.lb_name_to.setText("그룹채팅중입니다.");
				 			chatting.setTitle("그룹채팅중입니다. - " + chatting.e_name);
				 		}else{
				 			for(String str : v){	
				 				if(!str.equals(chatting.e_name)){
				 					chatting.lb_name_to.setText(str+"와(과) 대화중입니다.");
				 					chatting.setTitle(str+"와(과) 대화중입니다. - " + chatting.e_name);
				 				}else{
				 					
				 				}
				 			}
				 		}// 제목에 셋팅 
				 		name = new SimpleAttributeSet(); //
			    		StyleConstants.setAlignment(name, StyleConstants.ALIGN_CENTER);
			    		StyleConstants.setBackground(name, new Color(254, 130, 152));	
			    		StyleConstants.setBold(name, true);
			    		StyleConstants.setLeftIndent(name, 10);
			    		StyleConstants.setRightIndent(name, 10);
			    		StyleConstants.setSpaceBelow(name, 10);
			    		
				 		doc = chatting.textPane.getStyledDocument();
				 		//chatting.textPane.setText(null); 이걸 하면 그룹 초대시 아예 초기화 됨.
				 		chatting.textPane.setCaretPosition(doc.getLength());
				 		doc.insertString(doc.getLength(), chattingVO.getE_name()+"님이 접속하셨습니다.\n", name);
				 		chatting.textField.requestFocus();
				    	break; 
				 	case 2 : // disconnect 
				    	if(chattingVO.getM_id().equals(chatting.m_id)){		// 2-1) (내가 로그아웃할 때) Data의 Mid와 Client의 id가 같으면 로그아웃된다. 
				    		    		
				    	}else{												// 2-2) (다른 사람이 로그아웃하면) 내 리스트에서 제거한다. 
				    		name = new SimpleAttributeSet(); //
				    		StyleConstants.setAlignment(name, StyleConstants.ALIGN_CENTER);
				    		StyleConstants.setBackground(name, new Color(255, 215, 0));	
				    		StyleConstants.setBold(name, true);
				    		StyleConstants.setLeftIndent(name, 10);
				    		StyleConstants.setRightIndent(name, 10);
				    		StyleConstants.setSpaceBelow(name, 10);
				    		
					 		doc = chatting.textPane.getStyledDocument();
					 		//chatting.textPane.setText(null); 이걸 하면 그룹 초대시 아예 초기화 됨.
					 		chatting.textPane.setCaretPosition(doc.getLength());
					 		doc.insertString(doc.getLength(), chattingVO.getMessage()+"\n", name);
					 		chatting.dl_chatter.removeElement(chattingVO.getE_name());
					 		if(chatting.dl_chatter.size()<=1){
					 			chatting.lb_name_to.setText("대화가 종료되었습니다. ");
					 		}
					 		chatting.textField.requestFocus();
					 		chatting.textPane.setCaretPosition(doc.getLength());
					 		System.out.println(chattingVO.getE_name()+"님이 로그아웃 했슈");
				    	}
				    	break;
				    case 3 : // message : 서버에서 온 메세지를 출력한다.  			
				    	String msg = chattingVO.getMessage();
						Font f = new Font("맑은 고딕", Font.PLAIN, 12);
					    Rectangle2D r = f.getStringBounds(msg, new FontRenderContext
					    		(null, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT));
						
					    int width = (int) (r.getWidth());
					    int x = chatting.textPane.getWidth()-20;
				    	doc = chatting.textPane.getStyledDocument(); // 3-1) ChatClient의 textPane의 형식대로 내용을 가져온다.
				    	
				    	if(chattingVO.getE_name().equals(chatting.e_name)){				    		
				    		name = new SimpleAttributeSet(); //
				    		StyleConstants.setAlignment(name, StyleConstants.ALIGN_RIGHT);
				    		StyleConstants.setBold(name, true);
				    						    		
				    		message = new SimpleAttributeSet();
				    		StyleConstants.setBackground(message, new Color(255, 250, 205));				    		
				    		StyleConstants.setAlignment(message, StyleConstants.ALIGN_RIGHT);
				    		/*if(width<x){
				    			StyleConstants.setLeftIndent(message, x-width-15);
				    		}else{
				    			StyleConstants.setLeftIndent(message, 0);
				    		}*/
				    						    		
				    		labelStyle = new SimpleAttributeSet();
				    		ImageIcon icon = new ImageIcon(myIcon);
				    		JLabel label = new JLabel(icon);
				    		StyleConstants.setComponent(labelStyle, label);
				    		StyleConstants.setAlignment(labelStyle, StyleConstants.ALIGN_RIGHT);
				    		//StyleConstants.setSpaceAbove(labelStyle, 3);
				    		
				    		Date dNow = new Date( );
				    	    SimpleDateFormat ft = new SimpleDateFormat ("a hh:mm:ss ");
				    	    date = new SimpleAttributeSet();
				    		StyleConstants.setAlignment(date, StyleConstants.ALIGN_RIGHT);
				    		StyleConstants.setFontSize(date,9);

				    		//doc.insertString(doc.getLength(), chattingVO.getE_name() + " [" + chattingVO.getE_position() +"] ", name);
				    		//doc.insertString(doc.getLength(), "icon \n", labelStyle);	
				    		doc.insertString(doc.getLength(), ft.format(dNow), date);
				    		doc.insertString(doc.getLength(), chattingVO.getMessage()+"\n", message);
				    		chatting.textField.requestFocus();
				    		
				    	}else{
				    		name = new SimpleAttributeSet(); //
				    		StyleConstants.setAlignment(name, StyleConstants.ALIGN_LEFT);
				    		StyleConstants.setBold(name, true);
				    	
				    		message = new SimpleAttributeSet();
				    		StyleConstants.setBackground(message, new Color(255, 240, 245));
				    		StyleConstants.setAlignment(message, StyleConstants.ALIGN_LEFT);
				    		/*if(width<x){
				    			StyleConstants.setRightIndent(message, x-width-15);
				    		}else{
				    			StyleConstants.setRightIndent(message, 0);
				    		}*/
				    		   		
				    		labelStyle = new SimpleAttributeSet();
				    		ImageIcon icon = new ImageIcon(anotherIcon);
				    		JLabel label = new JLabel(icon);
				    		StyleConstants.setComponent(labelStyle, label);		
				    		//StyleConstants.setSpaceAbove(labelStyle, 3);
				    		
				    		Date dNow = new Date( );
				    	    SimpleDateFormat ft = new SimpleDateFormat ("a hh:mm:ss");
				    	    date = new SimpleAttributeSet();
				    		StyleConstants.setAlignment(date, StyleConstants.ALIGN_LEFT);
				    		StyleConstants.setFontSize(date,9);
				    	    
				    		doc.insertString(doc.getLength(), "icon", labelStyle);				    		
				    		doc.insertString(doc.getLength(), chattingVO.getE_name() + " [" + chattingVO.getE_position() +"] \n", name);
				    		doc.insertString(doc.getLength(), chattingVO.getMessage(), message);
				    		doc.insertString(doc.getLength(), ft.format(dNow)+"\n", date);
				    		
				    		if(!chatting.isFocused()){
					    		current = new CurrentState();
					    		/*cur = current.textPane.getStyledDocument();
					    		//cur.insertString(doc.getLength(), chattingVO.getMessage(), message);
					    		//cur.insertString(doc.getLength(), "채팅메q시지가 도착했습니다. \n", message);
					    		current.setVisible(true);
					    		chatting.textField.requestFocus();
					    		cur.insertString(doc.getLength(), "icon", labelStyle);*/
					    		if(chattingVO.getMessage().length()>=15){
					    			current.textArea.setText(chattingVO.getMessage().substring(0, 15));
					    		}else{
					    			current.textArea.setText(chattingVO.getMessage());
					    		}				    		
					    		current.textField.setText(chattingVO.getE_name() + " [" + chattingVO.getE_position() +"] \n");
					    		current.setVisible(true);
					    		
				    		}
				    		
				    		// chatting.textField.requestFocus();
				    	}
				    	
				    	doc.insertString(doc.getLength(), "\n", null);
				    	chatting.textPane.setCaretPosition(doc.getLength());			// 3-3) 스크롤이 항상 최하단에 있어서 , 최신 내용이 나오게 한다. 
				    	break;
				    case 4 : // invite
				    	break;		    
				 }
			}// end while
			
// <5. 반복문 종료 후 > - 사용한 스트림들을 닫아준다. 
			ois.close();					// 5-1.											
			is.close();
			oos.close();
			os.close();
			socket.close();					// 5-2. 접속 종료 시, 소켓을 닫는다. 
			socket = null;					// 5-3. 확실히 소켓을 정리하기 위해서, null값까지 준다. 
			chatting.dl_chatter.removeAllElements();	// 5-4. 접속자 리스트를 모두 깨끗하게 지워준다.  
			
		} catch (IOException e) {
			e.printStackTrace();											
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}						
	}

	public ObjectOutputStream getOos() {
	      return oos;
	   }


	   public void setOos(ObjectOutputStream oos) {
	      this.oos = oos;
	   }
	private ImageIcon createImageIcon(String string, String string2) {
		// TODO Auto-generated method stub
		return null;
	}

}
